Repository navigation
feat(libc): format num_put<char>::do_put as the console's libc does - #11054
Conversation
Progress report (0119103 → 1d31901)📈 System libraries: 49.69% (+0.04%, +9 implemented, -2 removed functions) ✅ 9 implemented
🗑️ 2 removed
Changed libraries (implemented exports)
|
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed exact head e6c4608. The eight vtable slots and their argument types match the inspected SDK layout; integer, pointer, floating, boolalpha, locale grouping/decimal-point, fill/adjustment, and width-reset paths are exercised by the new guest_locale cases. The PR documents the observed snprintf rounding differences and oversized negative-precision behavior instead of claiming parity where it differs. The author's 502,800-call comparison against the title's SDK libc.prx is detailed and reports integer/bool/pointer agreement and float differences only where snprintf text differs. I independently ran diff-check, conventions, and GCC C++20 syntax checks for LocaleSupport.cpp and GuestLocale.cpp; all passed. All applicable hosted jobs now pass, including the previously pending macOS Clang relinker; product Linux/Windows jobs are skipped by path policy. I could not run the runtime suite locally because this checkout lacks the SDL2 submodule, so the focused CTest and SDK comparison remain author-reported. I found no blocking issue in the reviewed change.
|
A Windows run of this head: Windows 11 Home 10.0.26200, WinLibs GCC 15.2.0 r7 (MinGW-w64 UCRT, posix-seh), CMake 4.3.1, Ninja 1.13.2, Release.
A note on the stack: this branch carries #11044 as Not run: Linux, macOS, the comparison against the title's AI-assisted: yes (Claude Code) |
The time_put facet's do_put formats % with the modifier and conversion through strftime and writes the result through the output iterator's stream buffer, following the SDK libc.prx: it stores into the put area while room remains, calls overflow otherwise, and marks the iterator failed when overflow returns eof or the buffer is null.
The num_put facet's eight do_put overloads build the console's printf format from the stream flags, format through snprintf and lay out the result as the SDK libc.prx does: thousands separators from the stream locale's numpunct, its decimal point, fill and width with left, right and internal adjustment, true and false names under boolalpha, and the console's prefix and infinity rules for floating point.
e6c4608 to
1d31901
Compare
|
Thanks for the Windows runs and for catching the stack. #11044's head is now |
|
Windows run, which the description doesn't cover: head
AI-assisted: yes (Claude Code); results above were run on this machine. |
|
A Windows rerun of the new head
AI-assisted: yes (Claude Code) |
What
All eight
num_put<char>::do_putoverloads threw (NumPutMethodUnsupported), so a title that writes a number to a stream (std::ostream << 42) stopped there. They now do what the SDKlibc.prxthat PPSA06416 ships insce_module/(title SDK 7.00) does, read from its disassembly (REVERSE_ENGINEERING, source 2). The module exports them aske36E2bqNmI(bool),I3+xmBWGPGo,nlAk46weq1w,H2KGT3vA7yQ,Vbeoft607aI(long, unsigned long, long long, unsigned long long),F+cp2B3cWNU,rLiFc4+HyHw(double, long double) and0xgFRKf0Lc4(const void*), with the helpers_Iput(0x95710) and_Fput(0x968d0). The structure is Dinkumware's, between the VC12 and current MSVC versions, with Sony's flag values:left/right/internalshowpointdec/oct/hexuppercaseshowbaseshowposscientific/fixed/hexfloatboolalpha%[+][#](showpos, showbase),lorll, theno,x/Xord/u, or%p, into a 64-byte buffer._Iputkeeps a sign, and withhexa0x, as the prefix.hexfloat.fixedvalues above 1e10 grow the buffer by|exp2| * 30103 / 100000, plus 50. The format is%[+][#][.*][L]withf(lowercase even withuppercase),a/A,e/Eorg/G. Unlike VC12,_Fputtakes a sign or else a leading0xas the prefix, so-0x1.8p+0gets internal fill after the-, and it skips grouping when the text after the prefix starts withI,N,iorn.ctype<char>, put the thousands separator of itsnumpunct<char>by the grouping, put its decimal point (wherelocaleconvputs the C one), then fill to the width: before the field, after the prefix (internal) or after the field (left), and reset the width to 0.boolwithoutboolalphacalls the facet's owndo_put(long)slot; with it, it writestruename()orfalsename()with the same fill.The facets come from the stream's locale as the inlined
use_facetdoes: the facet id (assigned under the libc lock if still 0), the locale's facet vector, then the global locale when the locale is transparent. Missing facets fall back to the C locale: a cachednumpunctfrom_Getcat, and digits left as they are forctype, since this library has noctype<char>::_Getcatand the console's C-localectypedoes not change them.numpunctstrings are freed with the console's large-allocation rule.GuestLocale.hppdescribes thenum_putandctypevtables; the iterator and stream buffer types come from #11044, which this builds on.Two known differences, recorded in a new debt entry:
snprintf, which converts floating point exactly and rounds ties to even. The module's converter keeps about 18 exact significant digits and prints later ones from an inexact scaling, so 1e10 at precision 22 is9999999999.999999999999there, and -2.5 at precision 0 is-3.sprintfwrote.Tested
Ubuntu 24.04 (WSL2) x86-64, GCC 13.3, Release, full build with
BUILD_TESTING=ON:libc.prx, converted by the relinker and loaded in a host process, compared against this library's facet with the same fake stream buffer and stream: 502,800 calls per side. They cover every overload, base and float field, showbase/showpos/uppercase/showpoint combination, all four adjustments, widths -1 to 30, precisions -1 to 40, values from 0 and denormals toINT64_MIN,UINT64_MAX, 1e300, 1e4000L, NaN and infinities, a stream buffer with room, two bytes of room withoverflowaccepting or refusing, a null buffer and a null put pointer, and the module's C locale or a locale with a guestnumpunct(,point,.separator, grouping\3\2, a 22-character and a 5000-character name).booland pointers match in every call.sprintfand this library'ssnprintfprint the same text for the same format, precision and value. The 58,880 calls that differ are exactly those where the twosprintfoutputs already differ.\1, both leaveinf,-infandnanungrouped and group1.2.3.4,5.guest_localegainsCheckNumPut: 19 calls with strings taken from the module's output, including internal fill with a sign and with0X, the-0x1.8p+0prefix, a custom locale with grouping\1\2(which would splitinfwithout the infinity rule), and the throw for precision -45. Taking0xas part of the prefix only underhexfloatafter the sign (VC12) fails it, and so does grouping infinities.ctest -R '^(guest_locale|guest_strftime|guest_wide_formatting|patched_libraries|conventions_unknown_nids)$': 5/5 pass.tools/progress.py: libc +8 implemented (NumPutBool…NumPutPointer),NumPutMethodUnsupportedremoved.python3 tools/check_conventions.py --base origin/main: passed.python3 tools/pr_overlap.py: no conflicting lines or same exports. Of the 39 pull requests it could not compare, only feat(libc): add std::__sce_v2::_Random_device, _Fiopen and setw #9526 names one of the types this touches, by creating anIosBasein its own code; none changesnum_put, the stream buffer types or this debt entry.Windows: not run by me.
guest_localepassed in @ycbuzi's run ofe6c4608736and in @wachi35676's run of this head1d31901c4b.Not tested: macOS, a title that writes numbers to a stream.
Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)